package cn.shop.gateway.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.io.watch.SimpleWatcher;
import cn.hutool.core.io.watch.WatchMonitor;
import cn.hutool.core.io.watch.watchers.DelayWatcher;
import cn.hutool.core.util.CharsetUtil;
import cn.shop.gateway.MainApp;
import cn.shop.gateway.db.DbUtil;
import cn.shop.gateway.http.ApiUtil;
import cn.shop.gateway.model.GameOrder;
import cn.shop.gateway.view.RootLayoutController;
import javafx.application.Platform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author : 李一涵
 * @date : Created in 2021-12-14 9:18
 * @description :
 */
public class WatchUtil {

    private final static Logger LOG = LoggerFactory.getLogger(WatchUtil.class);

    public static ConcurrentHashMap<String, WatchMonitor> watchMap = new ConcurrentHashMap<>();

    public static void watch(String path) {
        WatchMonitor monitor = watchMap.get(path);
        if (monitor == null) {
            monitor = WatchMonitor.createAll(path, new DelayWatcher(new SimpleWatcher() {
                @Override
                public void onModify(WatchEvent<?> event, Path currentPath) {
                    String file = currentPath.toString() + "\\" + event.context();
                    List<String> orders = FileUtil.readLines(new File(file), CharsetUtil.CHARSET_GBK);
                    if (CollectionUtil.isEmpty(orders)) {
                        return;
                    }
                    RootLayoutController controller = MainApp.stages.get("main");
                    if (controller != null) {
                        Platform.runLater(() -> controller.setAllCount(1));
                    }
                    String folder = currentPath.getRoot().toString() + currentPath.getName(0);
                    FileWriter.create(new File(file)).write("");
                    ResponseInfo<Object> result;
                    try {
                        result = sendOrder(orders, folder);
                        LOG.info("订单结果：{}", result);
                        if (result != null && result.getCode() == 1) {
                            if (controller != null) {
                                Platform.runLater(() -> controller.setSuccessCount(1));
                            }
                        } else {
                            if (controller != null) {
                                Platform.runLater(() -> controller.setFailCount(1));
                            }
                            DbUtil.saveFailOrder(folder, orders);
                        }
                    } catch (Exception e) {
                        if (controller != null) {
                            Platform.runLater(() -> controller.setFailCount(1));
                        }
                        DbUtil.saveFailOrder(folder, orders);
                        LOG.error("发送订单出错: {} {}", file, orders, e);
                    }

                }
            }, 500));
            monitor.start();
            watchMap.put(path, monitor);
        }
    }

    public static void stopWatch(String path) {
        WatchMonitor monitor = watchMap.remove(path);
        if (monitor != null) {
            IoUtil.close(monitor);
            LOG.info("停止{}的监控器", path);
        }
    }

    public static ResponseInfo<Object> sendOrder(List<String> lines, String folder) throws Exception {
        long templateId = DbUtil.getGameTemplate().orElse(0L);
        long uid = DbUtil.getMerchantInfo().orElse(0L);
        long partitionId = DbUtil.getGamePartitionByFolder(folder.toUpperCase());
        LOG.info("查询到的路径 {}", folder);
        List<GameOrder> orders = lines.stream().map(l -> format(l, templateId, partitionId)).collect(Collectors.toList());
        return ApiUtil.sendOrder(uid, orders);
    }

    private static GameOrder format(String line, long templateId, long partitionId) {
        String[] s = line.split("\\|");
        GameOrder order = new GameOrder();
        order.setTime(s[0]);
        order.setPartitionId(partitionId);
        order.setTemplateId(templateId);
        order.setPlayNickname(s[2]);
        order.setPlayAccount(s[3]);
        order.setItem(s[4]);
        order.setNum(Long.parseLong(s[5]));
        order.setAmount(new BigDecimal(s[6]));
        order.setRemark(s[7]);
        return order;
    }

}
